/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.service.rpc.SystemVariableRpcService;
import com.je.common.base.util.ArrayUtils;
import com.je.common.base.util.StringUtil;
import com.je.meta.rpc.excel.ExcelRpcService;
import com.je.meta.service.*;
import com.je.meta.service.excel.listener.ReadExcelListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

@Service
public class CommonExcelServiceImpl  implements CommonExcelService {

    @Autowired
    private DocumentInternalRpcService documentInternalRpcService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private SystemVariableRpcService systemVariableRpcService;
    @Autowired
    private ExcelRpcService excelRpcService;

    @Autowired
    protected CommonService commonService;


    @Autowired
    private GroupImporExceltExecutionService groupImporExceltExecutionService;

    @Autowired
    private SheetImporExceltExecutionService sheetImporExceltExecutionService;

    @Autowired
    private ExcelAssistService excelAssistService;

    @Override
    public JSONObject impData(DynaBean groupTemBean, String fileKey, HttpServletRequest request) {
        /*if (StringUtil.isEmpty(groupTemBean.getStr("JE_EXCEL_GROUPTEM_ID"))) {
            //构建创新基础信息
            commonService.buildModelCreateInfo(groupTemBean);
            groupTemBean = dynaBeanTemplate.doSave(groupTemBean);
        }*/
        return impData(groupTemBean.getStr("GROUPCODE"), fileKey, groupTemBean.getStr("JE_EXCEL_GROUPTEM_ID"), request);
    }

    @Override
    public JSONObject impData(String code, String fileKey, HttpServletRequest request) {
        return impData(code, fileKey, null, request);
    }

    @Override
    public JSONObject impData(String code, String fileKey, String groupTemId, HttpServletRequest request) {
        JSONObject jsonObject = new JSONObject();
        DynaBean group = metaResourceService.selectOneByNativeQuery("JE_CORE_EXCELGROUP", NativeQuery.build().eq("GROUPCODE",code));
        List<DynaBean> sheets = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_EXCELSHEET",
                NativeQuery.build().eq("JE_CORE_EXCELGROUP_ID",group.getStr("JE_CORE_EXCELGROUP_ID")).orderByAsc("SY_ORDERINDEX"));


        String dataPreview = group.getStr("EXCELGROUP_PRVIEW");
        if("1".equals(dataPreview)){
            NativeQuery nativeQuery = NativeQuery.build().eq("JE_CORE_EXCELGROUP_ID",group.getStr("JE_CORE_EXCELGROUP_ID"));
            if(StringUtil.isNotEmpty(groupTemId)){
                group.setStr("groupTemId",groupTemId);
                nativeQuery.ne("JE_EXCEL_GROUPTEM_ID",groupTemId);
            }
            metaResourceService.deleteByTableCodeAndNativeQuery("JE_EXCEL_GROUPTEM",nativeQuery);
        }

        File file = documentInternalRpcService.readFile(fileKey);
        ExcelReader excelReader =EasyExcel.read(file).build();
        List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList();
        JSONArray previewSheetInfo = new JSONArray();
        for(int i =0;i<readSheets.size();i++){
            ReadSheet readSheet = readSheets.get(i);
            DynaBean sheet = sheets.get(i);
            sheet.setStr("sheetName",readSheet.getSheetName());
            int startRow = sheet.getInt("STARTROWS", 0);
            readSheet = EasyExcel.readSheet(i).headRowNumber(startRow).registerReadListener(new ReadExcelListener(group,sheet,sheetImporExceltExecutionService,request)).build();
            excelReader.read(readSheet);
            if("1".equals(dataPreview)){
                previewSheetInfo.add(excelAssistService.buildSheetInfo(group,sheet));
            }
        }
        if ("1".equals(dataPreview)) {
            jsonObject.put("PREVIEW", "1");
            jsonObject.put("SHEETINFO", previewSheetInfo);
        } else {
            jsonObject.put("PREVIEW", "0");
        }
        // 这里千万别忘记关闭，读的时候会创建临时文件，到时磁盘会崩的
        excelReader.finish();
        return jsonObject;
    }

    /*public JSONObject impDataBack(String code, String fileKey, String groupTemId, HttpServletRequest request) {
        JSONObject returnObj = new JSONObject();
        *//**
         * 构建用户信息
         *//*
        Map<String, Object> ddMap = buildVariableList(request);
        *//**
         * 获取所有的excel数据
         *//*
       *//* FileBO fileBO = documentBusRpcService.readFile(fileKey);
        InputStream inputStream = fileBO.getFile();
        byte[] bytes = IoUtil.readBytes(inputStream);*//*
        ExcelReaderBuilder excelReaderBuilder = EasyExcel.read("C:\\Users\\77279\\Desktop\\test\\普通列表_2022-04-19.xlsx");
        //EasyExcel.read(new File("")).ignoreEmptyRow(true).build();
        ExcelReader excelReader =excelReaderBuilder.build();
        List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList();
        if(excelReader!=null){
            excelReader.finish();
        }
        DynaBean group = metaResourceService.selectOneByNativeQuery("JE_CORE_EXCELGROUP", NativeQuery.build().eq("GROUPCODE",code));
        List<DynaBean> sheets = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_EXCELSHEET",
                NativeQuery.build().eq("JE_CORE_EXCELGROUP_ID",group.getStr("JE_CORE_EXCELGROUP_ID")).orderByAsc("SY_ORDERINDEX"));
        Map<String,List<Map<Integer,Object>>> excelData = new HashMap<>();
        for(int i=0;i<sheets.size();i++){
            DynaBean sheetDynaBean = sheets.get(i);
            int excelIndex = sheetDynaBean.getInt("SY_ORDERINDEX")-1;
            int startRow = sheetDynaBean.getInt("STARTROWS", 0);
            int endRow = sheetDynaBean.getInt("EXCELSHEET_JSX", 0);
            List<Map<Integer,Object>> lists = excelReaderBuilder.sheet(excelIndex).headRowNumber(startRow).doReadSync();
            String SHEETNAME = readSheets.get(i).getSheetName();
            sheets.get(i).put("SHEETNAME",SHEETNAME);
            if(endRow>startRow){
                lists= lists.subList(0,endRow);
            }
            excelData.put(String.valueOf(excelIndex),lists);
        }
        *//**
         * 执行前逻辑
         *//*
        ExcelReturnVo excelReturnVo = groupImporExceltExecutionService.executeDataPre(ddMap,null);
        if(excelReturnVo.getCode()==-2||excelReturnVo.getCode()==-3){
            returnObj.put("code",excelReturnVo.getCode());
            returnObj.put("msg",excelReturnVo.getMsg());
            return returnObj;
        }
        *//**
         * 处理数据
         * JE_EXCEL_GROUPTEM:Excel数据导入临时组,用于临时存储数据
         *//*
        if("BEAN".equals(group.getStr("BEFORE_TYPE"))){
            excelData = excelReturnVo.getAllValues();
        }
        if(!excelData.isEmpty()){
            groupImporExceltExecutionService.executeData(group,groupTemId,ddMap,excelData,sheets,request,returnObj);
        }else{
            returnObj.put("code",-2);
            returnObj.put("msg","数据为空");
            returnObj.put("doType","GROUP_DATA");
            return returnObj;
        }

        *//**
         * 执行后逻辑sql，只支持sql
         *//*
        String dataPreview = group.getStr("EXCELGROUP_PRVIEW");
        if(!"1".equals(dataPreview)){
            //可以不用执行后的逻辑
           groupImporExceltExecutionService.executeDataAfter(ddMap,null);
        }
        *//**
         * 返回数据
         *//*
        return returnObj;
    }*/

    @Override
    public Map<String,Object> impPreviewData(String temIds,String groupCode, String temGroupId, HttpServletRequest request) {
        Map<String,Object> result =new HashMap<>();
        if (StringUtil.isEmpty(temIds) && StringUtil.isNotEmpty(temGroupId)) {
            List<DynaBean> temConfigs = metaResourceService.selectByTableCodeAndNativeQuery("JE_EXCEL_CONFIGTEMP",NativeQuery.build()
                    .eq("JE_EXCEL_GROUPTEM_ID",temGroupId));
            temIds = StringUtil.buildSplitString(ArrayUtils.getBeanFieldArray(temConfigs, "JE_EXCEL_CONFIGTEMP_ID"), ",");
        }

        DynaBean group = metaResourceService.selectOneByNativeQuery("JE_CORE_EXCELGROUP",NativeQuery.build()
                    .eq("GROUPCODE",groupCode));

        Map<String, Object> ddmap = buildVariableList(request);
        List<DynaBean> temConfigs = metaResourceService.selectByTableCodeAndNativeQuery("JE_EXCEL_CONFIGTEMP",NativeQuery.build().in("JE_EXCEL_CONFIGTEMP_ID",StringUtil.buildArrayToString(temIds.split(","))));
        for(DynaBean temConfig : temConfigs){
            String fieldConfigStrs = temConfig.getStr("CONFIGTEMP_FIELDCONFIG");
            DynaBean sheet =metaResourceService.selectOneByPk("JE_CORE_EXCELSHEET",temConfig.getStr("JE_CORE_EXCELSHEET_ID"));
            //excel中当前sheet的数据
            List<DynaBean> datas =  metaResourceService.selectByTableCodeAndNativeQuery("JE_EXCEL_DATATEMP",NativeQuery.build().eq("JE_EXCEL_CONFIGTEMP_ID",temConfig.getStr("JE_EXCEL_CONFIGTEMP_ID")).in("CODE","1","-1").orderByAsc("SY_ORDERINDEX"));
            List<DynaBean> lists = new ArrayList<>();
            for (DynaBean data : datas) {
                DynaBean dynaBean = new DynaBean(sheet.getStr("TABLECODE", ""), true);
                for (String fieldConfig : fieldConfigStrs.split(",")) {
                    String thisField = fieldConfig.split("~")[0];
                    String targerField = fieldConfig.split("~")[1];
                    dynaBean.set(targerField, data.get(thisField));
                }
                lists.add(dynaBean);
            }
            sheetImporExceltExecutionService.saveData(sheet,lists);
        }
        metaResourceService.deleteByTableCodeAndNativeQuery("JE_EXCEL_GROUPTEM",NativeQuery.build().eq("JE_CORE_EXCELGROUP_ID",group.getStr("JE_CORE_EXCELGROUP_ID")));
        groupImporExceltExecutionService.executeDataAfter(ddmap,null);
        return result;
    }

    @Override
    public void doUpdate(DynaBean dynaBean, HttpServletRequest request) {
        commonService.buildModelCreateInfo(dynaBean);
        metaResourceService.updateBean(dynaBean);
        String fileValue = dynaBean.getStr("GROUPTEM_FILE");
        if (StringUtil.isNotEmpty(fileValue)) {
            String fileKey = fileValue.split("\\*")[1];
            impData(dynaBean, fileKey, request);
            // 删除文件
            //documentBusService.delFilesByKey(Lists.newArrayList(fileKey), SecurityUserHolder.getCurrentUser().getUserId());
        }
    }

    private Map<String, Object> buildVariableList(HttpServletRequest request) {
        Map<String, Object> ddMap = systemVariableRpcService.formatCurrentUserAndCachedVariables();
        ddMap.putAll(getRequestParams(request));
        return  ddMap;
    }

}
